package com.nforce.linremote;

import java.util.List;
import java.util.Vector;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.nforce.linremote.model.Program;
import com.nforce.linremote.networking.SessionUtils;
import com.nforce.linremote.scripting.ScriptManager;
import com.nforce.linremote.serverapi.Library;

public class ProgramListFragment extends ListFragment {

    private static final String STATE_ACTIVATED_POSITION = "activated_position";

    private Callbacks mCallbacks = sDummyCallbacks;
    private Vector<Program> programs;
    private LayoutInflater mInflater;
    private CustomAdapter mAdapter;
    private Activity mActivity;

    private int mActivatedPosition = ListView.INVALID_POSITION;

    public interface Callbacks {
	public void onItemSelected(Bundle arg);
    }

    private static Callbacks sDummyCallbacks = new Callbacks() {
	@Override
	public void onItemSelected(Bundle arg) {
	}
    };

    public ProgramListFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);

	mActivity = getActivity();
	programs = new Vector<Program>();
	mAdapter = new CustomAdapter(getActivity(), android.R.layout.simple_list_item_activated_1, android.R.id.text1, programs);

	setListAdapter(mAdapter);

	loadPrograms();

	mInflater = (LayoutInflater) getActivity().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

	setHasOptionsMenu(true);
    }

    public void loadPrograms() {
	programs.clear();
	AsyncTask<Void, Void, Boolean> callJob = new AsyncTask<Void, Void, Boolean>() {

	    @Override
	    protected Boolean doInBackground(Void... params) {
		if (SessionUtils.isSessionActive()) {
		    AssetManager assetManager = mActivity.getAssets();
		    List<String> interfaces = Library.getList();
		    for (Program p : ScriptManager.loadScripts(assetManager, interfaces)) {
			programs.add(p);
		    }
		}
		return false;
	    }

	    @Override
	    protected void onPostExecute(Boolean result) {
		mAdapter.notifyDataSetChanged();
	    }
	};
	callJob.execute((Void) null);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
	super.onViewCreated(view, savedInstanceState);
	if (savedInstanceState != null && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
	    setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
	}
    }

    @Override
    public void onAttach(Activity activity) {
	super.onAttach(activity);
	if (!(activity instanceof Callbacks)) {
	    throw new IllegalStateException("Activity must implement fragment's callbacks.");
	}

	mCallbacks = (Callbacks) activity;
    }

    @Override
    public void onDetach() {
	super.onDetach();
	mCallbacks = sDummyCallbacks;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
	inflater.inflate(R.menu.program_list_menu, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
	switch (item.getItemId()) {
	    case R.id.menu_settings:
		Intent intent = new Intent(mActivity, SettingsActivity.class);
		startActivity(intent);
		return true;
	    case R.id.action_refresh:
		loadPrograms();
		return true;
	}
	return super.onOptionsItemSelected(item);
    }

    @Override
    public void onListItemClick(ListView listView, View view, int position, long id) {
	super.onListItemClick(listView, view, position, id);

	mCallbacks.onItemSelected(programs.get(position).toBundle());
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
	super.onSaveInstanceState(outState);
	if (mActivatedPosition != ListView.INVALID_POSITION) {
	    outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
	}
    }

    public void setActivateOnItemClick(boolean activateOnItemClick) {
	getListView().setChoiceMode(activateOnItemClick ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE);
    }

    private void setActivatedPosition(int position) {
	if (position == ListView.INVALID_POSITION) {
	    getListView().setItemChecked(mActivatedPosition, false);
	} else {
	    getListView().setItemChecked(position, true);
	}

	mActivatedPosition = position;
    }

    private class CustomAdapter extends ArrayAdapter<Program> {

	public CustomAdapter(Context context, int resource, int textViewResourceId, List<Program> objects) {
	    super(context, resource, textViewResourceId, objects);

	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
	    ViewHolder holder = null;

	    TextView item = null;

	    Program rowData = getItem(position);

	    if (null == convertView) {
		convertView = mInflater.inflate(R.layout.list_programs_row, null);
		holder = new ViewHolder(convertView);
		convertView.setTag(holder);
	    }

	    holder = (ViewHolder) convertView.getTag();
	    item = holder.getItem();
	    item.setText(rowData.getName() == null ? rowData.getInterfeiz() : rowData.getName());

	    return convertView;
	}
    }

    private class ViewHolder {
	private final View mRow;
	private TextView item = null;

	public ViewHolder(View row) {
	    mRow = row;
	}

	public TextView getItem() {
	    if (null == item) {
		item = (TextView) mRow.findViewById(R.id.programView);
	    }
	    return item;
	}
    }
}
